package com.mine.crawler.beans;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.apache.log4j.Logger;

/*
 * 	Tree class used to store parent/child relationship
 */
public class MySqlDBCategoryParentTreeLogical
{
	MySqlDBCategoryNodeLogical root;
	private Logger log = Logger.getLogger(MySqlDBCategoryParentTreeLogical.class);
	//String root;
	
	public MySqlDBCategoryParentTreeLogical(String local_root)
	{
		MySqlDBCategoryNodeLogical myRootNode = new MySqlDBCategoryNodeLogical(local_root);
		root = myRootNode;
	}
	
	public void AddChildrenFromList(MySqlDBCategoryNodeLogical NodeToAdd)
	{
		//search for Parent
		MySqlDBCategoryNodeLogical currentNode = root;
		MySqlDBCategoryNodeLogical newNode;
		String[] nodeList = NodeToAdd.getComplete_cat_name().split("/");
		int i=0;
		int nodeIndex = 0;
		StringBuffer strBuf = new StringBuffer("");
		
		while(nodeList.length > i)
		{
			if(currentNode.getCategory_name().equalsIgnoreCase(NodeToAdd.getCategory_name()))
				break;
			nodeIndex = currentNode.getChildren().indexOf(new MySqlDBCategoryNodeLogical(nodeList[i]));
			if(nodeIndex == -1)
			{
				strBuf.delete(0, strBuf.length());
				for(int j=0; j<=i ;j++)
				{
					strBuf.append(nodeList[j]);
					if(i!=j) 
						strBuf.append("/");
				}
				newNode = new MySqlDBCategoryNodeLogical(strBuf.toString());				
				currentNode.addChild(newNode);
				nodeIndex = currentNode.getChildren().indexOf(new MySqlDBCategoryNodeLogical(nodeList[i]));
			}
			else
				currentNode = currentNode.getChildren().get(nodeIndex);
			i = i+1;
		}
	}

	public MySqlDBCategoryNodeLogical search(MySqlDBCategoryNodeLogical toLocate)
	{
		MySqlDBCategoryNodeLogical currentNode = root;
		String[] nodeList = toLocate.getComplete_cat_name().split("/");
		int i=0;
		int nodeIndex = 0;
		
		while(nodeList.length >= i)
		{
			if(currentNode.getCategory_name().equalsIgnoreCase(toLocate.getCategory_name()))
			{
				return currentNode;
				//return true;
			}
			nodeIndex = currentNode.getChildren().indexOf(new MySqlDBCategoryNodeLogical(nodeList[i]));
			if(nodeIndex == -1)
			{
				break;
			}
			else
				currentNode = currentNode.getChildren().get(nodeIndex);
			i = i+1;
		}
		return null;
		//return false;
	}

	public MySqlDBCategoryNodeLogical searchParent(MySqlDBCategoryNodeLogical toLocate)
	{
		MySqlDBCategoryNodeLogical currentNode = root;
		List <MySqlDBCategoryNodeLogical> parentList = new ArrayList<MySqlDBCategoryNodeLogical>();
		MySqlDBCategoryNodeLogical parentNode = null;
		String[] nodeList = toLocate.getComplete_cat_name().split("/");
		int i=0;
		int nodeIndex = 0;
		
		while(nodeList.length >= i)
		{
			if(currentNode.getCategory_name().equalsIgnoreCase(toLocate.getCategory_name()))
			{
				
				return parentNode;
				//return true;
			}
			nodeIndex = currentNode.getChildren().indexOf(new MySqlDBCategoryNodeLogical(nodeList[i]));
			if(nodeIndex == -1)
			{
				break;
			}
			else
			{
				parentNode = currentNode;
				parentList.add(parentNode);
				currentNode = currentNode.getChildren().get(nodeIndex);
			}
			i = i+1;
		}
		return null;
		//return false;
	}

	public MySqlDBCategoryNodeLogical searchFileRelatedParent(MySqlDBCategoryNodeLogical toLocate)
	{
		MySqlDBCategoryNodeLogical currentNode = root;
		List <MySqlDBCategoryNodeLogical> parentList = new ArrayList<MySqlDBCategoryNodeLogical>();
		MySqlDBCategoryNodeLogical parentNode = null;
		String[] nodeList = toLocate.getComplete_cat_name().split("/");
		int i=0;
		int nodeIndex = 0;
		
		while(nodeList.length >= i)
		{
			if(currentNode.getCategory_name().equalsIgnoreCase(toLocate.getCategory_name()))
			{
				parentNode = actualParent(parentList);
				return parentNode;
				//return true;
			}
			nodeIndex = currentNode.getChildren().indexOf(new MySqlDBCategoryNodeLogical(nodeList[i]));
			if(nodeIndex == -1)
			{
				break;
			}
			else
			{
				parentNode = currentNode;
				parentList.add(parentNode);
				currentNode = currentNode.getChildren().get(nodeIndex);
			}
			i = i+1;
		}
		return null;
		//return false;
	}
	
	public boolean search_bool(MySqlDBCategoryNodeLogical toLocate)
	{
		if(!search(toLocate).equals(null))
			return true;
		else
			return false;
	}
	
	protected MySqlDBCategoryNodeLogical actualParent(List<MySqlDBCategoryNodeLogical>parentList)
	{	
		for(int i= (parentList.size()-1); i >=0; i--)
		{
			if(parentList.get(i).getCategory_id() >0)
				return parentList.get(i);
		}
		return null;
	}
	public void printTree()
	{
		MySqlDBCategoryNodeLogical currentNode = root;		
		Stack<MySqlDBCategoryNodeLogical> TreeStack = new Stack<MySqlDBCategoryNodeLogical>();
		List<MySqlDBCategoryNodeLogical> childList;// = new ArrayList<MySqlDBCategoryNode>();
		List<MySqlDBCategoryNodeLogical> markedDown = new ArrayList<MySqlDBCategoryNodeLogical>();
		
		TreeStack.addElement(currentNode);
		while(!TreeStack.empty())
		{
			log.info(currentNode.toString());
			markedDown.add(currentNode);
			childList = currentNode.getChildren();
			
			if(childList.isEmpty())
			{
				currentNode = TreeStack.pop();
				markedDown.add(currentNode);
			}
			else
			{
				for(int i = childList.size()-1;i>0;i--)
				{
					if(!markedDown.contains(childList.get(i)))
						TreeStack.addElement(childList.get(i));
				}
				//TreeStack.addElement(currentNode);
				currentNode = childList.get(0);
			}
			childList = null;
		}
	}
	
	public void AddRelatedCategoryUsingCatMap(Map<Integer, MySqlDBRelatedCategoryNode>localCatMap)
	{
		String query = "insert into related_categories (category_id, related_category_id)"+
		"values(?,?)";

		MySqlDBCategoryNodeLogical currentNode = root;		
		Stack<MySqlDBCategoryNodeLogical> TreeStack = new Stack<MySqlDBCategoryNodeLogical>();
		List<MySqlDBCategoryNodeLogical> childList;// = new ArrayList<MySqlDBCategoryNode>();
		List<MySqlDBCategoryNodeLogical> markedDown = new ArrayList<MySqlDBCategoryNodeLogical>();
		int related_cat = 0;
		Iterator<String> it;
		MySqlDBRelatedCategoryNode current_related_node = null;
		String current_related_node_name = null;
		
		TreeStack.addElement(currentNode);
		while(!TreeStack.empty())
		{
			{
				log.info("--Element-- "+currentNode.toString());
				
				it = currentNode.getRelated().iterator();
				while(it.hasNext())
				{
					current_related_node_name = (String)it.next();
					if(localCatMap.containsKey(new Integer(current_related_node_name.hashCode())) )
					{
						current_related_node = (MySqlDBRelatedCategoryNode)localCatMap.get
												(new Integer(current_related_node_name.hashCode())); 
						related_cat = current_related_node.getCategory_id();
						log.info("insert into related_categories (category_id, related_category_id)"+
							"values("+currentNode.getCategory_id()+","+related_cat+")");
					}
					current_related_node = null;
					current_related_node_name = null;
				}
			}
			
			
			markedDown.add(currentNode);
			childList = currentNode.getChildren();
			
			if(childList.isEmpty())
			{
				currentNode = TreeStack.pop();
				markedDown.add(currentNode);
			}
			else
			{
				for(int i = childList.size()-1;i>0;i--)
				{
					if(!markedDown.contains(childList.get(i)))
						TreeStack.addElement(childList.get(i));
				}
				//TreeStack.addElement(currentNode);
				currentNode = childList.get(0);
			}
			childList = null;
		}

	}
}
